Информационный блог Контроль. Программирование на заказ.

Главная страница

Delphi 7 Indy 10. Кодировка IdHTTP1.Post и IdHTTP1.Get | Запись № 000002 от 12.05.2015

Информационный блог Контроль. Программирование на заказ.  Программирование

Блог ведет фирма "Контроль".

Главная страница | Запись № 000002 от 12.05.2015
Delphi 7 Indy 10. Кодировка IdHTTP1.Post и IdHTTP1.Get
После установки последней десятой версии Indy возникли проблемы с кодировкой. Когда отправляешь Get или Post запрос на сайт, то в ответ получаешь за место русских символов знаки вопроса ?????

После долгих поисков решения этой проблемы в интернете, я понял, что придется разбираться самому. Было ясно, что ответ кроется в исходниках Indy. Наверняка в исходниках написано что-то типо: "Если неизвестный символ, то заменить на '?'". Начал поиски в исходных текстах по знаку вопроса. И результат не заставил себя ждать!

if UInt16(P^) > $007F then begin

  ABytes^ := Byte(Ord('?'));

end else begin

  ABytes^ := Byte(P^);

end;

Для работы с сайтами в кодировке utf-8 меняем команду ABytes^ := Byte(Ord('?')); на ABytes^ := Byte(P^)+176;. Почему именно +176? Если вы делали запрос на сайт в кодировке utf-8, то русские символы возвращаются со смещением на 176 знаков. Восстановив это смещение, мы получим исходный русский текст.

Для работы с сайтами в кодировке windows-1251 или вообще без кодировки меняем команду ABytes^ := Byte(Ord('?')); на ABytes^ := Byte(P^);. Но в данном случае потребуется дополнительно результат запроса провести через функцию UTF8Decode();. Например так: Memo1.Text := UTF8Decode(IdHTTP1.Get('www.site_windows-1251.ru'));.

Возникает вопрос, как и где все эти изменения сделать? Все просто. Открываем в Delphi свой проект. Переходит к разделу "uses". Находим там слово "IdHTTP". И нажимаем на него, при этом зажав клавишу "Ctrl". В открывшемся окошке также спускаемся к разделу "uses". Находим там слово "IdGlobal". И нажимаем на него, при этом зажав клавишу "Ctrl". В открывшемся окошке находим код, о котором писалось выше, и вносим необходимые изменения. После чего сохраняем и запускаем свой проект. Проверяем - теперь русские буквы распознаются!

Вторая часть вопроса, как передать русский текст в параметрах через IdHTTP1.Post(); используя TIdMultiPartFormDataStream.AddFormField();. Решение этого вопроса было найдено частично. В программе ничего не меняем, а со стороны сервера в php коде пишем следующее: quoted_printable_decode($_POST['ru_text']); и в результате получаем чистый русский текст.

И последнее, как передать русское имя отправляемого файла через IdHTTP1.Post(); используя TIdMultiPartFormDataStream.AddFile();. Решение этого вопроса также было найдено частично, но мне было этого достаточно. Во первых со стороны сервера все также придется использовать: quoted_printable_decode($_FILES['upload_ru_file']['name']);. Но в дополнение к этому в исходниках Indy придется внести изменения.

Открываем в Delphi свой проект. Переходит к разделу "uses". Находим там слово "IdHTTP". И нажимаем на него, при этом зажав клавишу "Ctrl". В открывшемся окошке также спускаемся к разделу "uses", проматываем дальше и ищем второй раздел "uses". Там находим слово "IdGlobalProtocols" и нажимаем на него, при этом зажав клавишу "Ctrl". Ищем в этом окошке фразу LANG_RUSSIAN: Result := idcs_KOI8_R;. Меняем ее на LANG_RUSSIAN: Result := idcs_ISO_8859_1;. После чего сохраняем и запускаем свой проект. Теперь при совместной работе Delphi + php мы получаем корректные русские имена файлов.

Надеюсь эта статья поможет Вам решить проблему с кодировкой. Не знаю как все эти изменения в исходниках Indy отразятся на работе других функций в дальнейшем. Но конкретно в моем проекте мне это помогло. Используйте данную статью на свой страх и риск. :)

Вопросы и комментарии:


Информационный блог Контроль. Программирование на заказ.
Информационный блог Контроль. Программирование на заказ.